package controllers

import (
	"encoding/json"
	"fmt"
	"github.com/astaxie/beego"
	"myapp/web/beegoapi/server/models"
	"strconv"
	"strings"
)

//Oprations for author
type AuthorController struct {
	beego.Controller
}

func (this *AuthorController) URLMapping() {
	this.Mapping("Post", this.Post)
	this.Mapping("GetAll", this.GetAll)
	this.Mapping("Get", this.Get)
	this.Mapping("Put", this.Put)
	this.Mapping("Delete", this.Delete)
}

// @Title Post
// @Description Creat Author
// @Param body body models.Author true "body for Author content"
// @Success 200
// @Failure 403 body is empty
// @router / [post]
func (this *AuthorController) Post() {
	var author models.Author
	if err := json.Unmarshal(this.Ctx.Input.RequestBody, &author); err == nil {
		id, err := models.CreateAuthor(&author)
		if err != nil {
			this.Data["json"] = err.Error()
		} else {
			this.Data["json"] = fmt.Sprintf("Create author success ，new author's id = %v", id)
		}
	} else {
		this.Data["json"] = err.Error()
	}
	this.ServeJson()
}

//@Title Get
//@Description Get Authors
//@Param query  query string false ""
//@Param fields query string false ""
//@Param sortby query string false ""
//@Param order  query string false ""
//@Param offser query string false ""
//@Param limit  query string false ""
//@Success 200
//@Failure 403
//@router / [get]
func (this *AuthorController) GetAll() {
	var query = make(map[string]string)
	var fields []string
	var sortby []string
	var order []string
	var offset int64
	var limit int64

	//query
	if queryStr := this.GetString("query"); queryStr != "" {
		for _, val := range strings.Split(queryStr, ",") {
			kv := strings.Split(val, "=")
			if len(kv) == 2 {
				query[kv[0]] = kv[1]
			} else {
				this.Data["json"] = "query input err"
				this.ServeJson()
				return
			}
		}
	}

	//fields
	if fieldsStr := this.GetString("fields"); fieldsStr != "" {
		for _, v := range strings.Split(fieldsStr, ",") {
			fields = append(fields, v)
		}
	}

	//sortby
	if sortbyStr := this.GetString("sortby"); sortbyStr != "" {
		for _, v := range strings.Split(sortbyStr, ",") {
			sortby = append(sortby, v)
		}
	}

	//order
	if orderStr := this.GetString("order"); orderStr != "" {
		for _, v := range strings.Split(orderStr, ",") {
			order = append(order, v)
		}
	}

	//offset
	if val, err := this.GetInt64("offset"); err == nil {
		offset = val
	}

	//limit
	if val, err := this.GetInt64("limit"); err == nil {
		limit = val
	}

	list, _, err := models.GetAuthors(query, fields, sortby, order, offset, limit)
	if err != nil {
		this.Data["json"] = err.Error()
	} else {
		this.Data["json"] = &list
	}
	this.ServeJson()
}

// @Title Get
// @Description Get Author By Id
// @Param id path string true ""
// @Success 200 {object} models.Author
// @Failure 403 :id is empty
// @router /:id [get]
func (this *AuthorController) Get() {
	id, _ := strconv.Atoi(this.Ctx.Input.Param(":id"))
	author, err := models.GetAuthorById(id)
	if err != nil {
		this.Data["json"] = err.Error()
	} else {
		this.Data["json"] = author
	}
	this.ServeJson()
}

//@Title Put
//@Description Update Author By Id
//@Param id   path string        true ""
//@Param body body models.Author true ""
//@Success 200
//@Failure 403 id or body is empty
//@router /:id [put]
func (this *AuthorController) Put() {
	id, _ := strconv.Atoi(this.Ctx.Input.Param(":id"))
	var author models.Author
	if err := json.Unmarshal(this.Ctx.Input.RequestBody, &author); err == nil {
		author.Id = id
		err = models.UpdateAuthorById(&author)
		if err != nil {
			this.Data["json"] = err.Error()
		} else {
			this.Data["json"] = fmt.Sprintf("Update id=%v success", id)
		}
	} else {
		this.Data["json"] = err.Error()
	}
	this.ServeJson()
}

//@Title Delete
//@Description Delete Author By Id
//@Param id path string true ""
//@Success 200
//@Failure 403 id is empty
//@router /:id [delete]
func (this *AuthorController) Delete() {
	id, _ := strconv.Atoi(this.Ctx.Input.Param(":id"))
	err := models.DeleteAuthorById(id)
	if err != nil {
		this.Data["json"] = err.Error()
	} else {
		this.Data["json"] = fmt.Sprintf("Delete id=%v success", id)
	}
	this.ServeJson()
}
